package cn.iocoder.yudao.module.ao.controller.admin.labschedule;

import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import org.springframework.web.multipart.MultipartFile;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;

import cn.iocoder.yudao.module.ao.controller.admin.labschedule.vo.*;
import cn.iocoder.yudao.module.ao.dal.dataobject.labschedule.LabScheduleDO;
import cn.iocoder.yudao.module.ao.service.labschedule.LabScheduleService;
import cn.iocoder.yudao.module.ao.service.labschedule.LabScheduleExcelParser;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.usermodel.Sheet;

@Tag(name = "管理后台 - 机房实训室课")
@RestController
@RequestMapping("/ao/lab-schedule")
@Validated
@Slf4j
public class LabScheduleController {

    @Resource
    private LabScheduleService labScheduleService;

    @Resource
    private LabScheduleExcelParser excelParser;

    @PostMapping("/create")
    @Operation(summary = "创建机房实训室课")
    @PreAuthorize("@ss.hasPermission('ao:lab-schedule:create')")
    public CommonResult<Long> createLabSchedule(@Valid @RequestBody LabScheduleSaveReqVO createReqVO) {
        return success(labScheduleService.createLabSchedule(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新机房实训室课")
    @PreAuthorize("@ss.hasPermission('ao:lab-schedule:update')")
    public CommonResult<Boolean> updateLabSchedule(@Valid @RequestBody LabScheduleSaveReqVO updateReqVO) {
        labScheduleService.updateLabSchedule(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除机房实训室课")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('ao:lab-schedule:delete')")
    public CommonResult<Boolean> deleteLabSchedule(@RequestParam("id") Long id) {
        labScheduleService.deleteLabSchedule(id);
        return success(true);
    }

    @DeleteMapping("/delete-list")
    @Parameter(name = "ids", description = "编号", required = true)
    @Operation(summary = "批量删除机房实训室课")
                @PreAuthorize("@ss.hasPermission('ao:lab-schedule:delete')")
    public CommonResult<Boolean> deleteLabScheduleList(@RequestParam("ids") List<Long> ids) {
        labScheduleService.deleteLabScheduleListByIds(ids);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得机房实训室课")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('ao:lab-schedule:query')")
    public CommonResult<LabScheduleRespVO> getLabSchedule(@RequestParam("id") Long id) {
        LabScheduleDO labSchedule = labScheduleService.getLabSchedule(id);
        return success(BeanUtils.toBean(labSchedule, LabScheduleRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得机房实训室课分页")
    @PreAuthorize("@ss.hasPermission('ao:lab-schedule:query')")
    public CommonResult<PageResult<LabScheduleRespVO>> getLabSchedulePage(@Valid LabSchedulePageReqVO pageReqVO) {
        PageResult<LabScheduleDO> pageResult = labScheduleService.getLabSchedulePage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, LabScheduleRespVO.class));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出机房实训室课 Excel")
    @PreAuthorize("@ss.hasPermission('ao:lab-schedule:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportLabScheduleExcel(@Valid LabSchedulePageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<LabScheduleDO> list = labScheduleService.getLabSchedulePage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "机房实训室课.xls", "数据", LabScheduleRespVO.class,
                        BeanUtils.toBean(list, LabScheduleRespVO.class));
    }

    @PostMapping("/get-sheet-names")
    @Operation(summary = "获取Excel文件中的工作表名称")
    @Parameter(name = "file", description = "Excel 文件", required = true)
    public CommonResult<List<String>> getSheetNames(@RequestParam("file") MultipartFile file) {
        try {
            if (file == null || file.isEmpty()) {
                return success(new ArrayList<>());
            }

            List<String> sheetNames = new ArrayList<>();
            try (Workbook workbook = WorkbookFactory.create(file.getInputStream())) {
                for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
                    Sheet sheet = workbook.getSheetAt(i);
                    if (sheet != null) {
                        sheetNames.add(sheet.getSheetName());
                    }
                }
            }

            log.info("成功获取工作表名称，文件: {}, 工作表: {}", file.getOriginalFilename(), sheetNames);
            return success(sheetNames);
        } catch (Exception e) {
            log.error("获取工作表名称失败", e);
            // 返回默认工作表名称，而不是抛出异常
            List<String> defaultSheets = new ArrayList<>();
            defaultSheets.add("Sheet1");
            return success(defaultSheets);
        }
    }

    @GetMapping("/get-import-template")
    @Operation(summary = "获得导入机房实训室课模板")
    public void importTemplate(HttpServletResponse response) throws IOException {
        // 手动创建导出 demo
        List<LabScheduleImportExcelVO> list = Arrays.asList(
                LabScheduleImportExcelVO.builder().term("2024-2025学年 第二学期").labName("本校区-博学楼-博学楼机房1")
                        .classSection("早1、1 08:30-09:15").mondayUsage("计算机科学与技术1班 Java程序设计 张老师")
                        .tuesdayUsage("").wednesdayUsage("软件工程2班 数据库原理 李老师")
                        .thursdayUsage("").fridayUsage("信息管理1班 Web开发 王老师").build(),
                LabScheduleImportExcelVO.builder().term("2024-2025学年 第二学期").labName("本校区-博学楼-博学楼机房2")
                        .classSection("2 09:25-10:10").mondayUsage("").tuesdayUsage("计算机科学与技术2班 算法设计 赵老师")
                        .wednesdayUsage("").thursdayUsage("软件工程1班 软件测试 刘老师")
                        .fridayUsage("").build()
        );
        // 输出
        ExcelUtils.write(response, "机房实训室课导入模板.xls", "机房实训室课列表", LabScheduleImportExcelVO.class, list);
    }



    @PostMapping("/import")
    @Operation(summary = "导入机房实训室课")
    // @PreAuthorize("@ss.hasPermission('ao:lab-schedule:import')") // 暂时注释权限控制
    @Parameter(name = "file", description = "Excel 文件", required = true)
    @Parameter(name = "updateSupport", description = "是否支持更新，默认为 false", example = "true")
    @Parameter(name = "sheetName", description = "工作表名称", required = false)
    public CommonResult<LabScheduleImportRespVO> importExcel(@RequestParam("file") MultipartFile file,
                                                      @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport,
                                                      @RequestParam(value = "sheetName", required = false) String sheetName) throws Exception {
        log.info("开始导入Excel文件，文件名: {}, 工作表: {}, 更新支持: {}", file.getOriginalFilename(), sheetName, updateSupport);

        // 使用新的解析器来解析复杂的课程表格式
        List<LabScheduleImportExcelVO> list = excelParser.parseExcel(file.getInputStream(), sheetName);
        log.info("Excel解析完成，解析到 {} 条数据", list.size());

        return success(labScheduleService.importLabScheduleList(list, updateSupport));
    }



}